/*
 * Copyright 2011-2023 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0.
 * See `LICENSE` in the project root for license information.
 */

package me.ijleex.platform.framework.util;

import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;

/**
 * 日期&星期计算工具.
 *
 * @author liym
 * @since 2023-03-02 10:43:36 新建
 */
public abstract class DateWeekUtils {

    private DateWeekUtils() {
    }

    /**
     * 获取指定前几周的起止日期，即周一至周日的日期
     *
     * @param n 前几周，0表示本周，1表示前一周，2表示前两周，3表示前三周，…
     * @return 当前日期前几周的起止日期，即 [周一，周日]
     */
    public static LocalDate[] getBeforeWeeksDateRange(int n) {
        final LocalDate beforeDate = LocalDate.now().minusDays(n * 7L);

        LocalDate monDate = getDateOfWeek(beforeDate, DayOfWeek.MONDAY);
        LocalDate sunDate = getDateOfWeek(beforeDate, DayOfWeek.SUNDAY);

        return new LocalDate[]{monDate, sunDate};
    }

    /**
     * 获取指定前几周的起止时间，即周一至周日的时间
     *
     * @param n 前几周，0表示本周，1表示前一周，2表示前两周，3表示前三周，…
     * @return 当前日期前几周的起止时间，即 [周一，周日]
     */
    public static LocalDateTime[] getBeforeWeeksTimeRange(int n) {
        LocalDate[] dateRange = getBeforeWeeksDateRange(n);

        LocalDateTime monDateTime = LocalDateTime.of(dateRange[0], LocalTime.MIN);
        LocalDateTime sunDateTime = LocalDateTime.of(dateRange[1], LocalTime.MAX);

        return new LocalDateTime[]{monDateTime, sunDateTime};
    }

    /**
     * 获取指定日期所在周的“周几”的日期
     *
     * @param date 日期
     * @param dayOfWeek 周几，如 周一、周五、周日、…
     * @return 周几的日期
     */
    private static LocalDate getDateOfWeek(LocalDate date, DayOfWeek dayOfWeek) {
        final int dateWeek = date.getDayOfWeek().getValue();
        final int thatWeek = dayOfWeek.getValue();
        LocalDate thatDate;
        if (dateWeek == thatWeek) {
            thatDate = date;
        } else if (dateWeek < thatWeek) {
            thatDate = date.plusDays(thatWeek - dateWeek);
        } else {
            thatDate = date.minusDays(dateWeek - thatWeek);
        }
        return thatDate;
    }

}
